#include "CSU8RP3216.h"
#include "stdint.h"
#include "DevicesADC.h"


void vADCInit(void)
{
    /*
        PT 数据标志位
    */
    PT3_1 = 0;
    PT3_2 = 0;

    /*
        PT3EN 输入/输出控制标志
        0: 定义为输入口
        1: 定义为输出口
    */
    PT3EN_1 = 0;
    PT3EN_2 = 0;

    /*
        PT3PU 上拉电阻使能标志
        0: 断开上拉电阻
        1: 使用上拉电阻
    */
    PT3PU_1 = 0;
    PT3PU_2 = 0;

    /*
        PT3CON 模拟/数字端口使能标志
        0: 定义为数字口
        1: 定义为模拟口
    */
    PT3CON_1 = 1;
    PT3CON_2 = 1;

    /* SRADCON0 config start */
    /*
        SRADACKS[1:0] ADC 输入信号获取时间
        00：16 个 ADC 时钟
        01：8 个 ADC 时钟
        10：4 个 ADC 时钟
        11：2 个 ADC 时钟
    */
    SRADACKS_1 = 0;
    SRADACKS_0 = 0;

    /*
        SRADCKS[1:0] ADC 采样时钟
        00：CPUCLK
        01：CPUCLK/2
        10：CPUCLK/4
        11：CPUCLK/8
    */
    SRADCKS_1 = 1;
    SRADCKS_0 = 1;
    /* SRADCON0 config end */

    /* SRADCON1 config start */
    /*
        SRADEN ADC 使能位
        1：使能
        0：禁止
    */
    SRADEN = 0;

    /*
        ADC 启动位/状态控制位
        1：开始，转换过程中
        0：停止，转换结束
    */
    SRADS = 0;

    /*
        OFTEN 转换结果选择控制位
        1：转换结果放在 SROFT 寄存器中
        0：转换结果放在 SRAD 寄存器中
    */
    OFTEN = 0;

    /*
        CALIF 校正控制位(OFTEN 为 0 时有效)
        1：使能校正，即 AD 转换的结果是减去了 SROFT 失调电压值
        0：禁止校正，即 AD 转换结果是没有减去 SROFT 失调电压值
    */
    CALIF = 0;

    /*
        ENOV 使能比较器溢出模式(CALIF 为 1 时有效)
        1：使能，上溢或下溢直接是减去后的结果
        0：禁止，下溢为 000h，上溢为 fffh
    */
    ENOV = 0;

    /*
        OFFSET 交换
        1：比较器两端信号交换
        0：比较器两端信号不交换（正端为信号，负端为参考电压）
    */
    OFFEX = 0;

    /*
        VREFS[1:0] ADC 参考电源选择 ，与 REFIN 寄存器位一起作用选择 ADC 参考电压

        REFIN = 0:
        00：VDD
        01：PT3.0 外部参考电源输入
        10：内部参考电压
        11：内部参考电压， PT3.0 可外接电容作为内置参考电压滤波使用，以提高精度。

        REFIN = 1:
        00：禁止
        01：禁止
        10：PT3.2 外部参考电源输入
        11：禁止
    */
    VREFS_1 = 0;
    VREFS_0 = 0;
    /* SRADCON1 config end */

    /* SRADCON2 config start */
    /*
        CHS[3:0] ADC 输入通道选择位
        0000：AIN0 输入
        0001：AIN1 输入
        0010：AIN2 输入
        0011：AIN3 输入
        0100：AIN4 输入
        0101：AIN5 输入
        0110：AIN6 输入
        0111：AIN7 输入
        1000：AIN8 输入
        1001：AIN9 输入，内部 1/8VDD
        1010：AIN10 输入，内部参考电压
        其它：保留
    */
    CHS_3 = 0;
    CHS_2 = 0;
    CHS_1 = 0;
    CHS_0 = 1;

    /*
        REF_SEL[1:0] 内部参考电压
        VREFS[1:0] 配置为 2’b10 或 2’b11，则可通过 REF_SEL [1:0]选择参考
        如下电压，若 VREFS[1:0]不是配置为 2’b10 或 2’b11，则以下位无效
        00：1.4V
        01：2.0V
        10：3.0V
        11：4.0V
    */
    REF_SEL_1 = 0;
    REF_SEL_0 = 0;
    /* SRADCON2 config end */

    /* SRADL config start */
    /*
        SRAD[7:0] ADC 数据的低 8 位，只可读
    */
    /* SRADL config end */

    /* SRADH config start */
    /*
        SRAD[11:8] ADC 数据的高 4 位，只可读
    */
    /* SRADH config end */

    /* SROFTL config start */
    /*
        SROFT[7:0] 校正值数据的低 8 位
    */
    /* SROFTL config end */

    /* SROFTH config start */
    /*
        SROFT[11:8] 校正值数据的高 4 位
    */
    /* SROFTH config end */

    /* METCH config start */
    /*
        REFOEN 内部参考电压从 PT3.0 输出使能位，输出 REF_SEL[1:0]选择的内部参考电压
        VREFS[1:0]为 01 时，禁止将 REFOEN 配置为 1。
        0：禁止内部参考电压输出
        1：使能内部参考电压输出
    */
    P30REFEN = 0;

    /*
        REFIN PT3.2 外部参考电压做 SAR_ADC 参考电压， 必须将 PT3CON[2]置 1做模拟口
        与 VREFS[1:0]共同选择外部参考电压，详见 VREFS[1:0]寄存器描述
    */
    METCH &= 0xEF;
    /* METCH config end */

    SRADEN = 1;
}

/*!
    \brief      ADC dma channel
    \param[in]  none
    \param[out] none
    \retval     none
*/
int32_t iADCGetValue(uint8_t ucChannel)
{
    int32_t uiValueSum = 0;
    uint16_t usValueNow = 0;
    uint8_t i = 0;

    for(i = 0; i < ADC1_SAMPLING_NUMBER; ++i)
    {
        /* 设置通道 */
        SRADCON2 &= 0x0F;
        SRADCON2 |= (ucChannel << 4);

        /* 启动转换 */
        SRADS = 1;
        while(SRADS);
        usValueNow = (SRADH << 8) | SRADL; //获取转换结果

        uiValueSum += usValueNow;
    }

   return ((uiValueSum / ADC1_SAMPLING_NUMBER * 5000) / 4095);
}
